package robots;

import java.util.Timer;
import java.util.TimerTask;

import maze.Coordinate;
import maze.Location;
import pacman.Game;
import robots.correction.RealRobotCorrector;
import sensors.realSensors.RealInfraredSensor;
import sensors.realSensors.RealLightSensor;
import sensors.realSensors.RealPilot;
import sensors.realSensors.RealUltrasonicSensor;
import simulation.Simulator;
import bluetoothCommunication.Communicator;


public class RealGhost extends OwnGhost {
	
	/**
	 * The communicator used by this ghost
	 */
	private Communicator communicator;
	private RealPilot pilot;

	public RealGhost(Game game, String name,Simulator simulator, Communicator comm) {
		this(game, new Location(20,20), name, simulator,comm);
	}
	
	public RealGhost(Game game, Location loc, String name,Simulator simulator, Communicator comm){
		super(game, loc, name);
		communicator=comm;
		setUltrasonicSensor(new RealUltrasonicSensor(this));
		setLightSensor(new RealLightSensor(this));
		setInfraredSensor(new RealInfraredSensor(this));
		setRobotCorrector(new RealRobotCorrector(this));
		pilot=new RealPilot(this, simulator);
		
	}
	Timer timer = new Timer();
	protected void scheduleBarcodeAnalyserTask(){
		
		BarcodeAnalyserTask barcodeAnalyserTask = new BarcodeAnalyserTask();
		int barcodeUpdatePeriod = 10;

		timer.schedule(barcodeAnalyserTask, 0, barcodeUpdatePeriod);
	}

//	public void travel(int distance, boolean interrupt, boolean correction) {
//		travel(distance,false,interrupt);
//	}
	@Override
	public void travel(int distance, boolean ignoreInSimulation,boolean interrupt){
//		boolean buttonNotPressed=true;
		boolean interrupted=false;
		if(interrupt){
			
			int currentSensorRotation=getSensorRotation();
			resetSensorMotor();
			int previousSpeed=communicator.getSpeed();
//			if(distance!=55){
//				
//				communicator.setSpeed(400);
//			}
			int distanceTravelled=communicator.travelInterrupt(distance, 15);
			rotateSensorMotor(currentSensorRotation);
			if(distanceTravelled<distance-8){
				pilot.realTravel(distance-distanceTravelled-40);
				interrupted=true;
				Coordinate currentCoordinate = this.getMaze().getCoordinateOfLocation(getLocation());
				this.getMaze().write(currentCoordinate.x,currentCoordinate.y,generateDirection(getRotation()) , (char)1, true);
			}
			communicator.setSpeed(previousSpeed);

		}
		else{
			pilot.realTravel(distance);

		}
		if(!ignoreInSimulation&&!interrupted){
			
			pilot.simulateTravel(distance);
			double rotRad= Math.toRadians(getRotation());
			double newX= getLocation().getX()+Math.cos(rotRad)*distance;
			double newY= getLocation().getY()+Math.sin(rotRad)*distance;
			this.setLocation(new Location(newX, newY));
			this.setCoordinate(this.getMaze().getCoordinateOfLocation(new Location(newX,newY)));
			protocolSender.sendPOSITION();
		}
	}
	//public void travelToNextSector()
	

//	public void rotate(int degrees, boolean correction) {
//		rotate(degrees,false);
//	}
	@Override
	public void rotate(int degrees, boolean ignoreInSimulation){
		pilot.realRotation(degrees);
		if(!ignoreInSimulation){
			pilot.simulateRotation(degrees);
			setRotation((getRotation()+degrees)%360);
		}
	}
	
	public void resetSensorMotor() {
		getCommunicator().resetSensorMotor();
		setSensorRotation(0);
	}
	
	
	
	public void setSpeed(int value){
		pilot.setSpeed(value);
		getCommunicator().setSpeed(value);
	}
	
	private void checkBarcodeState() {
		inBarcodeState = getCommunicator().hasBlackListValues();
	}
	
	protected void registerPacman(){
		boolean pacmanFound=scanForPacman();
		if(pacmanFound){
			Coordinate pacman=Coordinate.getCoordinateInDirection(getMaze().getCoordinateOfLocation(getLocation()), generateDirection());
			if(pacman!=null){
				setCoordinatePacman(pacman);
				protocolSender.sendPACMAN(pacman);

			}
		}
		if(!pacmanFound && hasFoundPacman() && Coordinate.getCoordinateInDirection(getMaze().getCoordinateOfLocation(getLocation()), generateDirection()).equals(getCoordinatePacman())){
			foundPacman(false);
			currentStrategy.unsetPacman();
			defaultStrategy.unsetPacman();
			secondaryStrategy.unsetPacman();
			
		}
	}
	private boolean scanForPacman() {
		// TODO Auto-generated method stub
		if(isPacmanInFrontOfMe())
			return true;
		getCommunicator().rotateSensorMotor(30);
		if(isPacmanInFrontOfMe())
			return true;
		getCommunicator().rotateSensorMotor(-60);
		if(isPacmanInFrontOfMe())
			return true;
		getCommunicator().rotateSensorMotor(30);
		return false;


	}

	private boolean isPacmanInFrontOfMe() {
		int directionIR = getCommunicator().getDirectionIR();
		if(directionIR==4||directionIR==5||directionIR==6){
			return true;
		}
		return false;
	}

	public String lookForBarcode(){
		String bc= getCommunicator().getBarcode();
		
		return bc;
	}


	/**
	 * Invokes the Update() method of the BarcodeAnalyser every period when scheduled.
	 * Takes appropriate action when a barcode is detected.
	 */
	class BarcodeAnalyserTask extends TimerTask {
		
//		public BarcodeAnalyser barcodeAnalyser;
		
		public BarcodeAnalyserTask(){
//			barcodeAnalyser = new BarcodeAnalyser();
//			barcodeAnalyser.whiteMargin = 40;
//			barcodeAnalyser.blackMargin = 40;
		}
		@Override
		public void run() {
			//verplaatst naar methode hierboven (lookForBarcode)
//			while (!terminated) {
//				String bc= getCommunicator().getBarcode();
//				if (!bc.equals("")&&inBarcodeState) {
//					System.out.println("Barcode detected: " + bc);
//					sendAndAddBarcode(bc);
//				}
//			}
		}
	}
	
	@Override
	public void rotateSensorMotor(int degrees) {
		communicator.rotateSensorMotor(degrees);
		setSensorRotation(getSensorRotation() + degrees);
	}

	public Communicator getCommunicator() {
		return communicator;
	}

	private void setCommunicator(Communicator communicator) {
		this.communicator = communicator;
	}

	@Override
	protected void victory() {
		communicator.victory();		
	}
	
}
	
	

